home *** CD-ROM | disk | FTP | other *** search
- /*
- FileList 1.4
- "FileSearch.c"
-
- Based on (and compatible with) the FileSearch library that was
- included with "Capp's Prime Editor Construction Kit". Added StuffIt
- (Classic and Deluxe) and Compactor archives support.
-
- The following routines may be used to step through the directories of
- one or more mounted volumes. The volumes may be MFS or HFS and, when
- used properly, can handle both MFS and HFS volumes intermixed without
- a lot of extra checking and can even be used if HFS is not running.
- StuffIt archives can be recognized and be treated as directories.
- */
-
- #include "FileSearch.h"
- #include "Utilities.h"
- #include "Main.h"
-
- #define STUFFIT 1 /* This is a StuffIt archive */
- #define COMPACTOR 2 /* This is a Compactor archive */
-
- /* ----- StuffIt compression methods ------------------------------------ */
-
- #define noComp 0 /* No compression */
- #define rleComp 1 /* RLE compression */
- #define lzwComp 2 /* LZW compression */
- #define hufComp 3 /* Huffman compression */
-
- #define encrypted 0x10 /* Bit set if encrypted */
- #define directory 0x20 /* Bit set if this is a directory */
- #define stop 0x21 /* End of directory */
-
- /* ---- StuffIt archive header ------------------------------------------ */
-
- typedef struct { /* 22 bytes */
- OSType signature; /* = 'SIT!' -- for verification */
- unsigned short numFiles; /* number of files in archive */
- unsigned long arcLength; /* length of entire archive incl. hdr */
- OSType signature2; /* = 'rLau' -- for verification */
- unsigned char version; /* version number (1 or 2=deluxe) */
- unsigned char reserved[7];
- } sitHdr;
-
- /* ----- StuffIt file header -------------------------------------------- */
-
- typedef struct { /* 112 bytes */
- unsigned char compRMethod; /* rsrc fork compression method */
- unsigned char compDMethod; /* data fork compression method */
- unsigned char fName[64]; /* a Str63 */
- OSType fType; /* file type */
- OSType fCreator; /* file creator */
- unsigned short FndrFlags; /* copy of Finder flags */
- unsigned long creationDate;
- unsigned long modDate;
- unsigned long rsrcLength; /* decompressed lengths */
- unsigned long dataLength;
- unsigned long compRLength; /* compressed lengths */
- unsigned long compDLength;
- unsigned short rsrcCRC; /* CRC of rsrc fork */
- unsigned short dataCRC; /* CRC of data fork */
- unsigned char rPad,dPad; /* pad bytes-valid for encr. entries */
- unsigned char reserved[4]; /* invalid data for now */
- unsigned short hdrCRC; /* CRC of file header */
- } fileHdr;
-
- /* ----- Compactor archive header --------------------------------------- */
-
- typedef struct { /* 8 bytes */
- unsigned char version; /* File format version code (1) */
- unsigned char part; /* Segment number */
- unsigned short arcID; /* Randomly generated archive ID nbr */
- unsigned long offset; /* Directory offset in this segment */
- } CompactorHdr;
- #define SIZEOF_CompactorHdr 8
-
- /* If the file is splitted into more than one segment "offset" is non-zero
- only for the last segment, and zero for the other segments. */
-
- /* ----- Compactor directory header ------------------------------------- */
-
- typedef struct { /* 7 + note_length bytes (not aligned) */
- unsigned char filler[4]; /* CRC for directory */
- unsigned char count[2]; /* Entries (including folders) */
- unsigned char arcNote[1]; /* Archive note (Pascal string) */
- } CompactorDirHdr;
- #define SIZEOF_CompactorDirHdr 7 /* sizeof() returns 8 ! */
-
- /* ----- Compactor directory entry (after file name) -------------------- */
-
- typedef struct { /* 45 bytes (not aligned) */
- unsigned char flags; /* ? */
- unsigned char data[4]; /* Offset to data */
- unsigned char type[4]; /* File type */
- unsigned char creator[4]; /* File creator */
- unsigned char cdate[4]; /* Creation date */
- unsigned char mdate[4]; /* Modifiaction date */
- unsigned char filler[8]; /* ? */
- unsigned char rsize[4]; /* Resource fork size */
- unsigned char dsize[4]; /* Data fork size */
- unsigned char crsize[4]; /* Compressed resource fork size */
- unsigned char cdsize[4]; /* Compressed data fork size */
- } CompactorFile;
- #define SIZEOF_CompactorFile 45 /* sizeof() returns 46 ! */
-
- /* ----- Static data ---------------------------------------------------- */
-
- typedef struct { /* Element of nesting stack: */
- long DirId; /* Directory ID */
- short index; /* File index */
- } ELEMENT;
-
- typedef struct {
- short MaxLevel; /* Maximal directory nesting level */
- short CurrentLevel; /* Current nesting level */
- short ArchiveLevel; /* To set end of archive */
- short VolumeIndex; /* Current volume index */
- Str255 VolumeName; /* Volume name */
- Str255 FileName; /* File/directory name */
- HVolumeParam Volume; /* Volume info */
- CInfoPBRec Info; /* File/directory info */
- short ArchiveRef; /* Archive file reference */
- short ArchiveType; /* Archive type */
- ELEMENT Stack[]; /* Nesting stack */
- } DATA;
-
- static DATA *Data = 0; /* Data block in application heap */
-
- /* #define USECRC */ /* Undefine this symbol to gain 622 bytes */
- #ifdef USECRC
- /*
- CRC computation used by Stuffit.
-
- The logic for this method of calculating the CRC 16 bit polynomial
- is taken from an article by David Schwaderer in the April 1985
- issue of PC Tech Journal.
-
- Not quite CCITT-CRC16... and definitely not xmodem CRC16.
- */
-
- #define CrcInit 0x0000 /* Initial CRC value */
-
- /* ----- CRC lookup table ----------------------------------------------- */
-
- static short crctab[] = {
- 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
- 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
- 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
- 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
- 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
- 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
- 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
- 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
- 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
- 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
- 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
- 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
- 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
- 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
- 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
- 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
- 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
- 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
- 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
- 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
- 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
- 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
- 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
- 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
- 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
- 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
- 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
- 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
- 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
- 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
- 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
- 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
- };
-
- /* ----- CRC calculation ------------------------------------------------ */
-
- static unsigned short CrcNew (
- register unsigned short crcval, /* Current CRC value */
- register Byte *buffer, /* Buffer (or part of) to verify */
- register unsigned long count) /* Length of buffer */
- {
- while (count--)
- crcval = (((crcval >> 8) & 0x00FF) ^
- crctab[(crcval^(*buffer++)) & 0x00FF]);
- return crcval;
- }
- #endif
-
- /* ----- Close archive -------------------------------------------------- */
-
- void CloseArchive (void)
- {
- register DATA *data = Data;
-
- if (!data || !data->ArchiveRef)
- return;
- FSClose(data->ArchiveRef);
- data->ArchiveRef = data->ArchiveType = 0;
- }
-
- /* ----- Check for archive ---------------------------------------------- */
-
- /*
- Type Creator
-
- StuffIt document 'SIT!' 'SIT!'
- AutoUnstuffIt application 'APPL' 'aust'
- StuffIt deluxe 'SITD' 'SIT!'
-
- Compactor document 'PACT' 'CPCT'
- Self-extracting application 'APPL' 'EXTR'
- */
-
- short IsArchive (register HFileInfo *f)
- {
- register DATA *data = Data;
- register short ref;
- register short type;
-
- if (!data || data->ArchiveRef)
- return 0;
-
- /* Check for:
- 1. StuffIt archives (type == 'SIT!' or 'SITD') or AutoUnstuffIt
- applications (type == 'APPL' and creator == 'aust')
- 2. Compactor archives (type == 'PACT') or self-extracting
- applications (type == 'APPL' and creator == 'EXTR') */
-
- if (f->ioFlFndrInfo.fdType == 'SIT!' ||
- f->ioFlFndrInfo.fdType == 'SITD' ||
- (f->ioFlFndrInfo.fdType == 'APPL' &&
- f->ioFlFndrInfo.fdCreator == 'aust')) {
- if (!Stuffit)
- return 0; /* Not enabled */
- type = STUFFIT;
- } else if (f->ioFlFndrInfo.fdType == 'PACT' ||
- (f->ioFlFndrInfo.fdType == 'APPL' &&
- f->ioFlFndrInfo.fdCreator == 'EXTR')) {
- if (!Compactor)
- return 0; /* Not enabled */
- type = COMPACTOR;
- } else
- return 0;
-
- /* Open the archive */
-
- {
- HFileParam p;
-
- FillMemory((Byte *)&p, sizeof(p), 0);
- p.ioVRefNum = f->ioVRefNum;
- p.ioDirID = CurrDir();
- p.ioNamePtr = f->ioNamePtr;
- if (PBHOpen(&p, FALSE))
- return 0;
- ref = p.ioFRefNum;
- }
-
- /* Read and verify archive header. Prepare archive walk thru */
-
- switch (type) {
- case STUFFIT:
- {
- sitHdr sit;
- long count;
-
- count = sizeof(sitHdr);
- if (FSRead(ref, &count, &sit) || GetEOF(ref, &count) ||
- sit.signature != 'SIT!' ||
- sit.signature2 != 'rLau' ||
- (sit.version != 1 && sit.version != 2) ||
- sit.arcLength != count) {
- FSClose(ref);
- return 0;
- }
- }
- break;
- case COMPACTOR:
- /* Read Compactor header and skip over file data. */
- {
- CompactorHdr hdr;
- long count;
-
- count = SIZEOF_CompactorHdr;
- if (FSRead(ref, &count, &hdr) ||
- hdr.version != 0x01 ||
- !hdr.offset ||
- SetFPos(ref, fsFromStart, hdr.offset)) {
- FSClose(ref);
- return 0;
- }
- count = 0;
- }
- /* Read directory header. */
- {
- CompactorDirHdr hdr;
- long count;
-
- count = SIZEOF_CompactorDirHdr;
- if (FSRead(ref, &count, &hdr) ||
- SetFPos(ref, fsFromMark, hdr.arcNote[0])) {
- FSClose(ref);
- return 0;
- }
- ++data->CurrentLevel;
- data->ArchiveLevel = data->CurrentLevel;
- BlockMove(hdr.count,
- &data->Stack[data->CurrentLevel].index, 2);
- }
- break;
- default:
- FSClose(ref);
- return 0;
- }
-
- data->ArchiveRef = ref;
- return data->ArchiveType = type;
- }
-
- /* ----- Get next file from StuffIt archive ----------------------------- */
-
- static CInfoPBPtr NextStuffitFile (void)
- {
- register DATA *data = Data;
- register HFileInfo *f;
- register short err;
- fileHdr file;
- long count;
-
- f = &data->Info.hFileInfo;
-
- /* Read and verify file header */
-
- count = sizeof(fileHdr);
- if (err = FSRead(data->ArchiveRef, &count, &file))
- goto done; /* eofErr */
- #ifdef USECRC
- if (file.hdrCRC !=
- CrcNew(CrcInit, (Byte *)&file, sizeof(fileHdr) - 2)) {
- err = ioErr;
- goto done;
- }
- #endif
-
- /* Interprete file header */
-
- switch (file.compRMethod & stop) {
- case directory: /* New directory */
- f->ioFlAttrib = 0x10;
- f->ioNamePtr = data->FileName;
- BlockMove(file.fName, f->ioNamePtr, file.fName[0] + 1);
- f->ioFlCrDat = file.creationDate;
- f->ioFlMdDat = file.modDate;
- break;
- case stop: /* End of directory */
- err = fnfErr;
- break;
- default: /* File */
- /* Skip resource and data fork */
- if (err = SetFPos(data->ArchiveRef, fsFromMark,
- file.compRLength + file.compDLength))
- goto done;
- f->ioNamePtr = data->FileName;
- BlockMove(file.fName, f->ioNamePtr, file.fName[0] + 1);
- f->ioFlFndrInfo.fdType = file.fType;
- f->ioFlFndrInfo.fdCreator = file.fCreator;
- f->ioFlFndrInfo.fdFlags = file.FndrFlags;
- f->ioFlCrDat = file.creationDate;
- f->ioFlMdDat = file.modDate;
- f->ioFlLgLen = file.rsrcLength;
- f->ioFlRLgLen = file.dataLength;
- break;
- }
- done:
- data->Info.hFileInfo.ioResult = err;
- return &data->Info;
- }
-
- /* ----- Get next file from Compactor archive --------------------------- */
-
- static CInfoPBPtr NextCompactorFile (void)
- {
- register DATA *data = Data;
- register HFileInfo *f;
- register short err;
- register Byte buffer[128 + SIZEOF_CompactorFile];
- register Boolean folder;
- long count;
-
- f = &data->Info.hFileInfo;
-
- if (data->CurrentLevel < data->ArchiveLevel) {
- err = ioErr;
- goto done;
- }
-
- /* End of directory ? */
-
- if (data->Stack[data->CurrentLevel].index == 0) {
- err = (data->CurrentLevel == data->ArchiveLevel) ?
- eofErr : /* End of archive */
- fnfErr; /* End of folder */
- PopDir();
- goto done;
- }
- for (err = data->ArchiveLevel; err <= data->CurrentLevel; ++err)
- --(data->Stack[err].index);
-
- /* Read file name length. */
-
- count = 1;
- if (err = FSRead(data->ArchiveRef, &count, buffer)) {
- err = ioErr; /* eofErr */
- goto done;
- }
- folder = (buffer[0] & 0x80) != 0;
- buffer[0] &= 0x7F;
-
- /* Read file name and directory file data */
-
- count = buffer[0] + /* Name length */
- (folder ?
- 2 : /* Folder entry */
- SIZEOF_CompactorFile); /* File entry */
- if (err = FSRead(data->ArchiveRef, &count, buffer + 1)) {
- err = ioErr; /* eofErr */
- goto done;
- }
-
- /* Copy name. */
-
- BlockMove(buffer, f->ioNamePtr = data->FileName, buffer[0] + 1);
-
- /* Copy directory file entry */
-
- if (folder) { /* Folder */
- f->ioFlAttrib = 0x10;
- if (data->CurrentLevel == (data->MaxLevel - 1)) {
- err = memFullErr;
- goto done;
- }
- ++data->CurrentLevel;
- /* Number of entries (including folders) in this folder */
- BlockMove(buffer + buffer[0] + 1,
- &data->Stack[data->CurrentLevel].index, 2);
- } else { /* File */
- register CompactorFile *p = (CompactorFile *)(buffer+buffer[0]+1);
- BlockMove(&p->type, &f->ioFlFndrInfo.fdType, sizeof(long));
- BlockMove(&p->creator, &f->ioFlFndrInfo.fdCreator, sizeof(long));
- BlockMove(&p->cdate, &f->ioFlCrDat, sizeof(long));
- BlockMove(&p->mdate, &f->ioFlMdDat, sizeof(long));
- BlockMove(&p->dsize, &f->ioFlLgLen, sizeof(long));
- BlockMove(&p->rsize, &f->ioFlRLgLen, sizeof(long));
- }
-
- done:
- data->Info.hFileInfo.ioResult = err;
- return &data->Info;
- }
-
- /* ----- Get next file from archive ------------------------------------- */
-
- CInfoPBPtr NextArchiveFile (void)
- {
- register DATA *data = Data;
-
- if (!data || !data->ArchiveRef)
- return 0;
- FillMemory((Byte *)&data->Info.hFileInfo, sizeof(CInfoPBRec), 0);
- switch (data->ArchiveType) {
- case 1:
- return NextStuffitFile();
- case 2:
- return NextCompactorFile();
- default:
- return 0;
- }
- }
-
- /* ----- Initialize everything ------------------------------------------ */
-
- /*
- Allocates data block and an an internal stack for the use of the file
- search routines. Returns TRUE if successful, FALSE otherwise. It must be
- called before calling any other file search routines. Parameter is the
- maximum nesting level of directories. If <= 0 then 128 will be used.
- */
-
- Boolean FileSearchOpen (register short nLevels)
- {
- if (Data)
- return FALSE; /* Data block already allocated! */
- if (nLevels <= 0)
- nLevels = 128; /* Use default of 128 nesting levels */
- else
- if (nLevels == 1)
- ++nLevels; /* At least 2 levels */
- if (Data = (DATA *)NewPtrClear(sizeof(DATA) + nLevels*sizeof(ELEMENT)))
- Data->MaxLevel = nLevels;
- return Data != 0;
- }
-
- /* ----- Releases the storage allocated by FileSearchOpen --------------- */
-
- void FileSearchClose (void)
- {
- if (Data) {
- DisposPtr(Data);
- Data = 0;
- }
- }
-
- /* ----- Prepare volume walk thru --------------------------------------- */
-
- /*
- If VRefNum is zero, then things are initialzed internally so that each
- subsequent call to NextVol will return each of the mounted volumes. The
- contents of the HVolumeParam struct will be undefined. If VRefNum is
- non-zero, then it may be a real VRefNum, a WDDirID, or a drive number.
- If a drive number is given, then the VRefNum will be in ioVRefNum. If
- a WDDirID is given, then the WDDirID will be in ioVRefNum (despite
- HGetVInfo's forcing a real VRefNum to be there; this allows you to,
- say, search all files in or below the current working directory. Note
- that, if HFS is not running, then ioVSigWord will be zero and all
- following fields will be undefined. When you pass a non-zero value
- to FirstVol, calls to NextVol will yield undefined results.
- */
-
- HVolumeParam *FirstVol (register short VRefNum)
- {
- register DATA *data = Data;
-
- if (!data)
- return 0;
- if (VRefNum) {
- data->CurrentLevel = -1;
- data->Volume.ioNamePtr = data->VolumeName;
- data->Volume.ioVRefNum = VRefNum;
- data->Volume.ioVolIndex =
- data->Volume.ioVSigWord = 0;
- PBHGetVInfo(&data->Volume, FALSE);
- if (VRefNum < 0)
- data->Volume.ioVRefNum = VRefNum;
- } else
- data->VolumeIndex = 0;
- return &data->Volume;
- }
-
- /* ----- Get next volume ------------------------------------------------ */
-
- /*
- Returns a pointer to the HVolumeParam info for the next mounted volume.
- If there is no next volume, then the ioResult will contain nsvErr.
- As noted above, ioVSigWord will be zero if HFS is not running; it will
- contain 0xD2D7 if the volume is an MFS volume and HFS is running, and
- it will contain 0x4244 if it is an HFS volume.
- */
-
- HVolumeParam *NextVol (void)
- {
- register DATA *data = Data;
-
- if (!data)
- return 0;
- data->CurrentLevel = -1;
- data->Volume.ioNamePtr = data->VolumeName;
- data->Volume.ioVolIndex = ++(data->VolumeIndex);
- data->Volume.ioVSigWord = 0;
- PBHGetVInfo(&data->Volume, FALSE);
- return &data->Volume;
- }
-
- /* ----- Prepare file walk thru ----------------------------------------- */
-
- /*
- Initializes things internally so that each subsequent call to NextFile
- will return each file/directory in the given volume/directory.
- If DirID is zero, then the root directory of the volume last selected
- with FirstVol or NextVol is used. If DirID is non-zero, then the
- directory with that ID on the volume last selected with FirstVol or
- NextVol will be used (if the volume is MFS, then the DirID will be
- ignored). If FirstFile has been called before for the current
- volume, then the current status of the search for that directory is
- saved before starting the new directory search. The saved status may
- be restored with PopDir (see below). Note that searches can be nested
- no deeper than 128 levels. If an attempt is made to go beyond that,
- then FirstFile will ignore it and the next call to NextFile will return
- the next file at the current level.
- */
-
- void FirstFile (register long DirID)
- {
- register DATA *data = Data;
- register ELEMENT *p;
-
- if (!data || data->CurrentLevel == (data->MaxLevel - 1))
- return;
- p = data->Stack + ++(data->CurrentLevel);
- p->DirId = IsHFSVol(data->Volume) ? DirID : 0;
- p->index = 0;
- }
-
- /* ----- Get next file -------------------------------------------------- */
-
- /*
- Returns a pointer to the file info for the next file in the current
- directory. If there is no next file, then the ioResult will contain
- fnfErr. If the current volume is an MFS volume, then the pointer
- returned will actually be a pointer to a FileParam struct, which is
- a subset of the CInfoPBRec struct.
- */
-
- CInfoPBPtr NextFile (void)
- {
- register DATA *data = Data;
- register ELEMENT *p;
- register HFileInfo *f;
-
- if (!data)
- return 0;
- f = &data->Info.hFileInfo;
- p = data->Stack + data->CurrentLevel;
- f->ioNamePtr = data->FileName;
- f->ioVRefNum = data->Volume.ioVRefNum;
- f->ioFDirIndex = ++(p->index);
- f->ioDirID = p->DirId;
- if (IsHFSVol(data->Volume))
- PBGetCatInfo(&data->Info, FALSE);
- else {
- PBGetFInfo(&data->Info, FALSE);
- f->ioFlAttrib &= 0xEF;
- }
- return &data->Info;
- }
-
- /* ----- Current volume ------------------------------------------------- */
-
- /*
- Returns the vRefNum of the volume last returned by FirstVol or NextVol.
- */
- /*
- short CurrVol (void)
- {
- return Data ? Data->Volume.ioVRefNum : 0;
- }
- */
- /* ----- Current level -------------------------------------------------- */
-
- /*
- Returns the number of "saved" directory searches; i.e., the level of
- directory nesting, unless you've skipped one or more levels
- deliberately.
- */
- /*
- short CurrLevel (void)
- {
- return Data ? Data->CurrentLevel : 0;
- }
- */
- /* ----- Current directory ---------------------------------------------- */
-
- /*
- Returns the DirID of the directory containing the file last returned by
- NextFile. If the file is on an MFS volume, then a zero will be returned.
- */
-
- long CurrDir (void)
- {
- register DATA *data = Data;
-
- return data ? data->Stack[data->CurrentLevel].DirId : 0;
- }
-
- /* ----- Pop directory -------------------------------------------------- */
-
- /*
- Restores the most recently saved search status (saved with FirstFile).
- If there are no saved searches left, PopDir returns FALSE; otherwise, it
- returns TRUE.
- */
-
- Boolean PopDir (void)
- {
- register DATA *data = Data;
-
- if (!data || !data->CurrentLevel)
- return FALSE;
- --(data->CurrentLevel);
- return TRUE;
- }
-